package cn.edu.xust.service.impl;

import cn.edu.xust.Ro.DeviceEntityRo;
import cn.edu.xust.Ro.MulHotelWtRo;
import cn.edu.xust.configuration.exception.Default200Exception;
import cn.edu.xust.configuration.exception.ErrorConstant;
import cn.edu.xust.entity.WtdataEntity;
import cn.edu.xust.Ro.WtRo;
import cn.edu.xust.service.WtdataService;
import cn.edu.xust.util.PageUtils;
import cn.edu.xust.util.Query;
import com.alibaba.fastjson2.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.edu.xust.dao.DeviceDao;
import cn.edu.xust.entity.DeviceEntity;
import cn.edu.xust.service.DeviceService;

import javax.annotation.Resource;

import static cn.edu.xust.util.BCDUtils.reverseAndCombine;
import static cn.edu.xust.util.BCDUtils.reverseSplit;


@Slf4j
@Service("deviceService")
public class DeviceServiceImpl extends ServiceImpl<DeviceDao, DeviceEntity> implements DeviceService {


    @Resource
    @Lazy
    WtdataService wtdataService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<DeviceEntity> page = this.page(
                new Query<DeviceEntity>().getPage(params),
                new QueryWrapper<DeviceEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public DeviceEntity getByName(String ammeterId) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("name", ammeterId);
        return baseMapper.selectOne(wap);
    }

    @Override
    public List<DeviceEntity> getByName(String ammeterId, String type) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("name", ammeterId).eq("type", type);
        return baseMapper.selectList(wap);
    }

    @Override
    public List<DeviceEntity> getByHotelRoom(String hotelid, String roomname) {

        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid).eq("roomname", roomname);
        return baseMapper.selectList(wap);


    }

    /** 解析水表 超仪科技水表协议
     * FEFEFE6810885015000535008116901F00300000002C000000002C0000000000000000006D16
     * FEFEFE68 10 54410324200000   81 16 1F9000  0002  00002C  0000   00002C  000000000000000000F416
     * FEFEFE68 10 54410324200000   81 16 1F9000  0002  00002C  0000   00002C  000000000000000000F416
     * FEFEFE68 10 54410324200000   81 16 901F00  0002   1200   2C  0000   00002C  000000000000000000F416
     * 02.00  0012 =>02
     * 解析，之后再将数据返回给调用者
     * FEFEFE  固定标致 [0-6)
     * 68      起始 6-8
     * 10      冷热水 8-10
     * 88501500053500 地址10-24
     * 81      控制码 24-26
     * 16      数据长度 26-28
     * 1F9000  数据标识[固定]28-34
     * 3000    当前累计流量34-38     00.30 L
     * 0000    水表数据高位38-42 00 0000.30l
     * 2C      截断 42-44
     * 0000    结算日累计流量 44-48     0000 L
     * 0000    水表数据高位48-52 00 0000.30l 38-41
     * 2C       截断 42-54
     * 00000000000000 时间 yyyyMMddHHmmss 54-68
     * 0000     状态 00开 01关 68-72
     * 6D       校验码 72-74
     * 16       结束码 74-76
     */
    @Override
    public WtdataEntity parsePersistwt(String message, String timetype) throws Default200Exception {
        if (message.length() != 76) {
            log.info("水表解析失败:{}", message);
            throw new Default200Exception(ErrorConstant.wt_data_parse_err);
        }
        boolean c1 = "FEFEFE".equals(message.substring(0, 6));
        boolean c2 = "68".equals(message.substring(6, 8));
        //boolean c3 = "10".equals(message.substring(8, 10));
        boolean c4 = "81".equals(message.substring(24, 26));
        boolean c5 = "1F9000".equals(message.substring(28, 34));
        if (!(c1 && c2 && c4 && c5)) {
            return new WtdataEntity();
        }

        String hotcold = message.substring(8, 10);
        String mac = message.substring(10, 24);
        mac = reverseSplit(mac);
        String datelen = message.substring(26, 28);

        String dangqianleiji = message.substring(34, 38);
        String dangqianleiji_high = message.substring(38, 42);

        String jiesuanrileiji = message.substring(44, 48);
        String jiesuanrileiji_high = message.substring(48, 52);

        String codetime = message.substring(54, 68);


        WtRo wtRo = new WtRo();
        wtRo.setMac(mac);
        DeviceEntity de = getByName(mac);
        if (de == null) {
            throw new Default200Exception(ErrorConstant.not_found);
        }
        wtRo.setDatelen(datelen);
        wtRo.setHotcold("10".equals(hotcold) ? "冷水" : "11".equals(hotcold) ? "热水" : "未知" + hotcold);


        //南硕的读
        if ("nanshuo".equals(de.getModel())) {
            String s = reverseAndCombine(dangqianleiji, dangqianleiji_high);
            double leiji = Double.parseDouble(s) / 100;
            String s1 = reverseAndCombine(jiesuanrileiji, jiesuanrileiji_high);
            double rileiji = Double.parseDouble(s1) / 100;
            wtRo.setCurrentCumulativeflow(String.valueOf(leiji));
            wtRo.setAccumulatedTrafficDay(String.valueOf(rileiji));
        } else {
            //好像是一样的读法....
            String s = reverseAndCombine(dangqianleiji, dangqianleiji_high);
            double leiji = Double.parseDouble(s) / 100;
            String s1 = reverseAndCombine(jiesuanrileiji, jiesuanrileiji_high);
            double rileiji = Double.parseDouble(s1) / 100;
            wtRo.setCurrentCumulativeflow(String.valueOf(leiji));
            wtRo.setAccumulatedTrafficDay(String.valueOf(rileiji));
        }
        try {
            wtRo.setCodetime(DateUtils.parseDate(codetime, "yyyyMMddHHmmss"));
        } catch (Exception e) {
            wtRo.setCodetime(null);
        }
        //存入数据库
        WtdataEntity wtdataEntity = new WtdataEntity();
        wtdataEntity.setGatewayid(de.getGatewayid());
        wtdataEntity.setDeviceid(de.getId());
        wtdataEntity.setCurrentcumulativeflow(wtRo.getCurrentCumulativeflow());
        wtdataEntity.setAccumulatedtrafficday(wtRo.getAccumulatedTrafficDay());
        wtdataEntity.setDevicename(wtRo.getMac());
        wtdataEntity.setCtime(new Date());
        wtdataEntity.setTimetype(timetype);
        log.info("timetype:{}", timetype);
        if ("day".equals(timetype)) {
            wtdataEntity.setTimetypeflag(DateUtils.format(new Date(), "yyyy-MM-dd"));
        }
        wtdataService.save(wtdataEntity);
        return wtdataEntity;
    }

    public static void main(String[] args) {
        //String message="FEFEFE 68 11 22013007242000 81 16 1F9000 2000 00002C000000002C000000000000000000D516";//新
//        String message = "FEFEFE68112201300724200081161F9000200000002C000000002C000000000000000000D516";//超仪
//        String message = "FEFEFE68101200000000000081161F9000100010002C100010002C0000000000000000FF6716";//118
       // String message = "FEFEFE6810050021112400008116901F00680000002C680000002C00000O0000000OOOFF4016";//嘉荣华
        String message =  "FEFEFE681004002506240000811690IF00000000002C000000002C000000000000000OFF6816";//嘉荣华
       //String message="FEFEFE 68 10 06200424200000 81 16 1F9000 0015 00002C000000002C0000000000000000009916";//old
//          String message="FEFEFE68100620042420000081161F9000001500002C000000002C0000000000000000009916";
        log.info("水表解析{}", message);
        if (message.length() != 76) {
            log.info("长度不正确");
//            return new WtdataEntity();
        }
        boolean c1 = "FEFEFE".equals(message.substring(0, 6));
        boolean c2 = "68".equals(message.substring(6, 8));
        //要兼容新的
        // boolean c3 = "10".equals(message.substring(8, 10));
        boolean c4 = "81".equals(message.substring(24, 26));
        boolean c5 = "1F9000".equals(message.substring(28, 34));
        if (!(c1 && c2 && c4 && c5)) {
            log.info("格式不正确");
//            return new WtdataEntity();
        }

        String dangqianleiji = message.substring(34, 38);
        String dangqianleiji_high = message.substring(38, 42);

        //好像是一样的读法....
        String s = reverseAndCombine(dangqianleiji, dangqianleiji_high);
        double leiji = Double.parseDouble(s) / 100;


        log.info("解析水表读数：{}", leiji);

    }

    @Override
    public List<DeviceEntity> getByHotel(String hotelid) {

        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid);
        return baseMapper.selectList(wap);

    }

    @Override
    public List<DeviceEntity> getByHotelRoomAngType(String hotelid, String roomname, String type) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid).eq("roomname", roomname);
        wap.eq("type", type);
        return baseMapper.selectList(wap);
    }

    @Override
    public List<DeviceEntity> getByHotelAndClassify(String hotelid, String classify) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid).eq("classify", classify);
        return baseMapper.selectList(wap);
    }

    @Override
    public DeviceEntity getByHRType(String hotelid, String roomid, String type) {

        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>()
                .eq("hotelid", hotelid)
                .eq("type", type)
                .eq("roomname", roomid);
        return baseMapper.selectOne(wap);
    }

    @Override
    public List<DeviceEntity> getByHotels(ArrayList<String> list) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().in("hotelid", list);
        return baseMapper.selectList(wap);
    }

    @Override
    public List<DeviceEntityRo> getRoomsByHotel(String hotelid) {

        return baseMapper.getRoomsByHotel(hotelid);


    }

    @Override
    public List<DeviceEntity> getByHotel(String hotelid, String roomname, String mac, List<String> type) {


        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid);
        if (StringUtils.isNotEmpty(roomname)) {
            wap.like("roomname", roomname);
        }
        if (StringUtils.isNotEmpty(mac)) {
            wap.like("name", mac);
        }
        if (!type.isEmpty()) {
            wap.in("nickname", type);
        }
        return baseMapper.selectList(wap);
    }

    @Override
    public DeviceEntity getByHotelRoomAngNickName(String hotelid, String roomname, String nickname) {

        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid);
        wap.eq("roomname", roomname);
        wap.eq("nickname", nickname);
        return baseMapper.selectOne(wap);

    }

    @Override
    public List<DeviceEntity> getByGatewayids(List<Integer> gids) {

        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().in("gatewayid", gids);
        return baseMapper.selectList(wap);


    }

    @Override
    public List<DeviceEntity> getByHotelAndType(String hotelid, String type) {
        QueryWrapper<DeviceEntity> wap = new QueryWrapper<DeviceEntity>().eq("hotelid", hotelid);
        wap.eq("type", type);
        return baseMapper.selectList(wap);



    }


}